package com.alibaba.citrus.cr.forecast.functions.forecastorder.entity;

import com.alibaba.citrus.cr.common.util.SpringContextUtil;
import com.alibaba.citrus.cr.forecast.functions.forecastorder.ability.ForecastOrderLineAbility;
import com.alibaba.citrus.cr.forecast.repository.ForecastOrderLineQueryRepository;
import com.alibaba.citrus.cr.forecast.repository.ForecastOrderLineWriteRepository;
import com.alibaba.citrus.cr.forecast.repository.ForecastOrderQueryRepository;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSONObject;
import com.epoch.app.crforecastsales.model.dto.BatchUpdateForAnalysingRequest;
import com.epoch.app.crforecastsales.model.enums.ForecastDealStatusSEO;
import com.epoch.app.crforecastsales.sdo.ForecastOrderLineSDO;
import lombok.Getter;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @Author yuanDeng
 * @Date 2021/9/15 15:13
 **/
@Getter
public class ForecastOrderLineEntity {
    private static final Log log = Log.getLogger(ForecastOrderLineEntity.class);

    private ForecastOrderLineSDO forecastOrderLineSDO;

    private static ForecastOrderQueryRepository forecastOrderRepository;

    private static ForecastOrderLineWriteRepository forecastOrderLineWriteRepository;

    private static ForecastOrderLineQueryRepository forecastOrderLineRepository;

    private static ForecastOrderLineAbility forecastOrderLineAbility;

    static {
        forecastOrderRepository = SpringContextUtil.getBean(ForecastOrderQueryRepository.class);
        forecastOrderLineRepository = SpringContextUtil.getBean(ForecastOrderLineQueryRepository.class);
        forecastOrderLineWriteRepository = SpringContextUtil.getBean(ForecastOrderLineWriteRepository.class);
        forecastOrderLineAbility = SpringContextUtil.getBean(ForecastOrderLineAbility.class);
    }

    public static ForecastOrderLineEntity of(ForecastOrderLineSDO forecastOrderLineSDO) {
        ForecastOrderLineEntity forecastOrderLineEntity = new ForecastOrderLineEntity();
        forecastOrderLineEntity.forecastOrderLineSDO = forecastOrderLineSDO;
        return forecastOrderLineEntity;
    }

    public static boolean setOrderLineStatusToAnalyzing(List<ForecastOrderLineEntity> forecastOrderLineEntities) {
        List<Long> ids=new ArrayList<>();

        for (ForecastOrderLineEntity forecastOrderLineEntity : forecastOrderLineEntities) {
            if (Objects.isNull(forecastOrderLineEntity.getForecastOrderLineSDO())) {
                continue;
            }
            ids.add(forecastOrderLineEntity.getForecastOrderLineSDO().getId());
            //todo 批量重置分析状态为分析中 20220913 ,modify by myw
//            forecastOrderLineEntity.getForecastOrderLineSDO().setDealStatus(ForecastDealStatusSEO.ANALYSIS_ING.getStatus());
//            forecastOrderLineEntity.getForecastOrderLineSDO().setAnalysisTime(new Date());
////            batchAnalysisOrdersRequest.add(forecastOrderLineEntity.getForecastOrderLineSDO());
//            if (!forecastOrderLineWriteRepository.updateForAnalysis(forecastOrderLineEntity.forecastOrderLineSDO)) {
//                log.error("Set order line:{} status to:{} failed", forecastOrderLineEntity.forecastOrderLineSDO.getMainOrderBizId(),
//                        forecastOrderLineEntity.forecastOrderLineSDO.getDealStatus());
//            }
        }
        BatchUpdateForAnalysingRequest batchUpdateForAnalysingRequest = new BatchUpdateForAnalysingRequest();
        batchUpdateForAnalysingRequest.setDealStatus(ForecastDealStatusSEO.ANALYSIS_ING.getStatus());
        batchUpdateForAnalysingRequest.setAnalysisTime(new Date());
        batchUpdateForAnalysingRequest.setOrderLineIds(ids);
        return forecastOrderLineWriteRepository.batchUpdateForAnalysing(batchUpdateForAnalysingRequest);
    }

    @Deprecated
    public static boolean analysis(List<ForecastOrderLineEntity> forecastOrderLineEntities) {

        List<ForecastOrderLineSDO> batchAnalysisOrdersRequest = new ArrayList<>();
        for (ForecastOrderLineEntity forecastOrderLineEntity : forecastOrderLineEntities) {
            batchAnalysisOrdersRequest.add(forecastOrderLineEntity.forecastOrderLineSDO);
        }

        /*Map<String, List<ForecastOrderLineSDO>> collect = Nullable.stream(batchAnalysisOrdersRequest)
                .collect(Collectors.groupingBy(ForecastOrderLineSDO::getMainOrderId));
        //查询最低起运量
        Integer number=null;
        for (String key:collect.keySet()){
            List<ForecastOrderLineSDO> forecastOrderLineSDOList = collect.get(key);
            int count = Nullable.stream(forecastOrderLineSDOList).mapToInt(it -> {
                int i = Integer.parseInt(it.getQuantity());
                return i;
            }).sum();

            if(count<number){
                Nullable.stream(forecastOrderLineSDOList).forEach(it->{
                    it.setRefuseReason("预报数量不足起运量");
                    it.setRefuseReasonCode("");
                    it.setAnalysisTime(new Date());
                    it.setDealStatus(ForecastDealStatusSEO.ANALYSIS_ED.getStatus());
                });
            }
        }
        //分组根据货品
        List<ForecastOrderLineSDO> forecastOrderLineSDOs=new ArrayList<>();
        Map<String, List<ForecastOrderLineSDO>> collect1 = Nullable.stream(batchAnalysisOrdersRequest)
                .filter(it->it.getDealStatus()==ForecastDealStatusSEO.ANALYSIS_ING.getStatus())
                .collect(Collectors.groupingBy(ForecastOrderLineSDO::getScItemId));
        for (String key:collect1.keySet()){
            //根据货品id查询库存,和渠道部门
            Integer ScItemNumber=null;
            //计算该货品需要数量 count；

            List<ForecastOrderLineSDO> forecastOrderLineSDOList = collect1.get(key);
            Integer count = Nullable.stream(forecastOrderLineSDOList).mapToInt(it -> {
                int i = Integer.parseInt(it.getQuantity());
                return i;
            }).sum();
            //回复数量赋值
            //库存数量大于预报数量全量回复
            if(count<=ScItemNumber){
                Nullable.stream(forecastOrderLineSDOList).forEach(it->{
                    it.setPredictReplyAmount(Integer.parseInt(it.getQuantity()));
                    it.setAnalysisTime(new Date());
                    forecastOrderLineSDOs.add(it);
                });
            }
            if (count>ScItemNumber){
                //先根据是否分解库存有效
                List<ForecastOrderLineSDO> collect2 = Nullable.stream(batchAnalysisOrdersRequest)
                        .filter(it->it.getDealStatus()==1*//*是否分解库存有效过滤*//*)
                        .collect(Collectors.toList());
                int sum = Nullable.stream(collect2).mapToInt(it -> {
                    int i = Integer.parseInt(it.getQuantity());
                    return i;
                }).sum();

                for(ForecastOrderLineSDO forecastOrderLineSDO:forecastOrderLineSDOList){
                    //先根据是否分解库存有效，、

                    //根据订单信息查询用户优先策略批量查询，

                    //存在的策略的按时间排序
                    //循环第一个数组
                    if(count>Integer.parseInt(forecastOrderLineSDO.getQuantity())){
                        //优先用户按照先到先得回复
                        forecastOrderLineSDO.setPredictReplyAmount(Integer.parseInt(forecastOrderLineSDO.getQuantity()));
                        forecastOrderLineSDO.setAnalysisTime(new Date());
                        forecastOrderLineSDOs.add(forecastOrderLineSDO);
                        count-=Integer.parseInt(forecastOrderLineSDO.getQuantity());
                    }if(count>0&&count<Integer.parseInt(forecastOrderLineSDO.getQuantity())){
                        //如果货品数量小于与预报数量
                        forecastOrderLineSDO.setPredictReplyAmount(count);
                        forecastOrderLineSDO.setAnalysisTime(new Date());
                        forecastOrderLineSDOs.add(forecastOrderLineSDO);
                        count-=Integer.parseInt(forecastOrderLineSDO.getQuantity());
                    }else {
                        forecastOrderLineSDO.setRefuseReason("库存不足");
                        forecastOrderLineSDO.setRefuseReasonCode("");
                        forecastOrderLineSDO.setDealStatus(ForecastDealStatusSEO.ANALYSIS_ED.getStatus());
                        forecastOrderLineSDO.setAnalysisTime(new Date());
                        forecastOrderLineSDOs.add(forecastOrderLineSDO);
                    }
                    //循环非优先客户赋值,如果还有货品
                    if(count>0){
                        //循环非优先客户赋值,
                        if (count>Integer.parseInt(forecastOrderLineSDO.getQuantity())){
                            forecastOrderLineSDO.setPredictReplyAmount(Integer.parseInt(forecastOrderLineSDO.getQuantity()));
                            forecastOrderLineSDO.setAnalysisTime(new Date());
                            count-=Integer.parseInt(forecastOrderLineSDO.getQuantity());
                            forecastOrderLineSDOs.add(forecastOrderLineSDO);
                        }if(count>0&&count<Integer.parseInt(forecastOrderLineSDO.getQuantity())){
                            //如果货品数量小于与预报数量
                            forecastOrderLineSDO.setPredictReplyAmount(count);
                            count-=Integer.parseInt(forecastOrderLineSDO.getQuantity());
                            forecastOrderLineSDO.setRefuseReason("库存不足");
                            forecastOrderLineSDO.setAnalysisTime(new Date());
                            forecastOrderLineSDOs.add(forecastOrderLineSDO);
                        }else {
                            forecastOrderLineSDO.setRefuseReason("库存不足");
                            forecastOrderLineSDO.setRefuseReasonCode("");
                            forecastOrderLineSDO.setAnalysisTime(new Date());
                            forecastOrderLineSDOs.add(forecastOrderLineSDO);
                            forecastOrderLineSDO.setDealStatus(ForecastDealStatusSEO.ANALYSIS_ED.getStatus());
                        }
                    }
                }
            }


        }
        Map<String, List<ForecastOrderLineSDO>> collect2 = Nullable.stream(forecastOrderLineSDOs)
                .collect(Collectors.groupingBy(ForecastOrderLineSDO::getMainOrderId));
        //根据预报订单回复数量进行起运量校验
        for (String key:collect2.keySet()){
            Integer count=0;
            List<ForecastOrderLineSDO> forecastOrderLineSDOList = collect2.get(key);
            for(ForecastOrderLineSDO forecastOrderLineSDO:forecastOrderLineSDOList){
                if(null!=forecastOrderLineSDO.getQuantity()){
                    Integer quantity = forecastOrderLineSDO.getPredictReplyAmount();
                    count+=quantity;
                }
            }
            if(count<number){
                Nullable.stream(forecastOrderLineSDOList).forEach(it->{
                    it.setAnalysisTime(new Date());
                    it.setRefuseReason("不足分配");
                    it.setRefuseReasonCode("");
                    it.setDealStatus(ForecastDealStatusSEO.ANALYSIS_ED.getStatus());
                });
            }
        }
        //修改数据库
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOs) {
            boolean b1 = forecastOrderLineWriteRepository.analysis(forecastOrderLineSDO);
        }



        for (Object obj : batchAnalysisOrdersRequest) {
            //订单进行分析分析后赋值，报保存
            ForecastOrderLineSDO forecastOrderLine =JSONObject.parseObject(JSONObject.toJSONString(obj),ForecastOrderLineSDO.class);
            forecastOrderLine.setAnalysisTime(new Date());
            forecastOrderLine.setPredictReplyAmount(1);
            forecastOrderLine.setAnalysisReason("926库存不足");
            forecastOrderLine.setRefuseReason("926库存不足");
            //查询该组织渠道最小启运量  查询预报订单主单信息  计算  预报订单 总数量（不足起运量）break；
            //查询该货品的每日可售库存总数量a （再按照当前渠道的维度判断分配到该维度上的数量）（该渠道可用量），剩余可用库存是数量，若库存数量大于预报订单数量，全部回复
            //若数量不足 查询预报订单是否存在优先客户，  满足优先客户（若数量满足不了优先客户，按时间先到先得（先得全得，还是比例分配）），已满足优先客户后数量分配（按先到先得）给非优先客户
            //回复数量确认完毕  计算该预报订单的主单  回复总数量与最小启用量比较   不足启运量（不足分配）break；
            //检查活动量或者活动余额
            //检查信贷（先款后货及账期）
            //剩余活动量不足拆单处理，后续生成不同的销售订单（主要特价促销活动）
            forecastOrderLine.setDealStatus(ForecastDealStatusSEO.ANALYSIS_ED.getStatus());//分析完成
            boolean b1 = forecastOrderLineWriteRepository.analysis(forecastOrderLine);
        }
*/
        return true;
    }

    @Deprecated
    public static boolean batchRefuseForecast(List<ForecastOrderLineEntity> forecastOrderLineEntities) {
        List<ForecastOrderLineSDO> batchAnalysisOrdersRequest = new ArrayList<>();
        for (ForecastOrderLineEntity forecastOrderLineEntity : forecastOrderLineEntities) {
            batchAnalysisOrdersRequest.add(forecastOrderLineEntity.forecastOrderLineSDO);
        }
        //forecastOrderLineAbility
        return true;
    }

    @Deprecated
    public static boolean updateDealStatus(List<ForecastOrderLineEntity> forecastOrderLineEntities) {
        List<ForecastOrderLineSDO> batchAnalysisOrdersRequest = new ArrayList<>();
        for (ForecastOrderLineEntity forecastOrderLineEntity : forecastOrderLineEntities) {
            batchAnalysisOrdersRequest.add(forecastOrderLineEntity.forecastOrderLineSDO);
        }
        for (Object obj : batchAnalysisOrdersRequest) {
            //订单进行分析分析后赋值，报保存
            ForecastOrderLineSDO forecastOrderLine = JSONObject.parseObject(JSONObject.toJSONString(obj), ForecastOrderLineSDO.class);
            boolean b1 = forecastOrderLineWriteRepository.updateForAnalysis(forecastOrderLine);
        }

        return true;
    }
}
